package cn.yunbamboos.db.core;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.db.ReadInitDataSQL;
import cn.yunbamboos.db.metadata.TableMetadata;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

public class H2DB extends BaseDB {

    private static final Logger logger = LoggerFactory.getLogger(H2DB.class);

    private static final String DB_DIR = System.getProperty("user.dir") + File.separator + "db" + File.separator + "H2";

    private boolean init = false;

    @Override
    public void checkDBDir() {
        logger.info("H2 data dir {}", DB_DIR);
        // 判断数据库目录是否存在
        FileUtil.mkdir(DB_DIR);
        // 判断数据库目录是否为空
        if (FileUtil.isDirEmpty(new File(DB_DIR))) {
            String DB_NAME = System.getProperty("DB_NAME", "db");
            // jdbc:h2:/home/app/db/H2/ivas-service;DB_CLOSE_DELAY=6;MODE=MySQL;AUTO_RECONNECT=TRUE;AUTO_SERVER=TRUE;
            String JDBC_URL = StrUtil.format("jdbc:h2:{}{}{};DB_CLOSE_DELAY=6;MODE=MySQL;AUTO_RECONNECT=TRUE;AUTO_SERVER=TRUE;database_to_upper=false;", DB_DIR, File.separator, DB_NAME);
            String USER = System.getProperty("DB_USER", "root");
            String PASSWORD = System.getProperty("DB_PASSWORD", "root");
            logger.info("create H2 db {}{}{}", DB_DIR, File.separator, DB_NAME);
            // 创建H2数据库
            try {
                // 加载H2数据库驱动
                Class.forName("org.h2.Driver");
                // 根据连接URL，用户名，密码获取数据库连接
                Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
                conn.close();
            } catch (ClassNotFoundException | SQLException e) {
                logger.error(e.getMessage(), e);
            }
            this.init = true;
        }
    }

    @Override
    public void connect() {
        String DB_DRIVER = System.getProperty("DB_DRIVER", "org.h2.Driver");
        String DB_NAME = System.getProperty("DB_NAME");
        String DB_USER = System.getProperty("DB_USER", "root");
        String DB_PASSWORD = System.getProperty("DB_PASSWORD", "root");
        dataSource = new HikariDataSource();
        dataSource.setDriverClassName(DB_DRIVER);
        dataSource.setJdbcUrl(StrUtil.format("jdbc:h2:{}{}{};DB_CLOSE_DELAY=6;MODE=MySQL;AUTO_RECONNECT=TRUE;AUTO_SERVER=TRUE;database_to_upper=false;", DB_DIR, File.separator, DB_NAME));
        dataSource.setUsername(DB_USER);
        dataSource.setPassword(DB_PASSWORD);
        dataSource.setAutoCommit(false);
        dataSource.setMaximumPoolSize(10);
        dataSource.setMinimumIdle(1);
    }

    @Override
    public boolean existTable(TableMetadata tableMetadata) {
        // H2 SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC' AND TABLE_NAME = 'ALARM'
        String sql = StrUtil.format("SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'PUBLIC' AND TABLE_NAME = '{}'", tableMetadata.getName());
        logger.info("execute exist table sql {}", sql);
        return executeExistTableSql(sql);
    }

    @Override
    public void createTable(TableMetadata tableMetadata) {
        String sql = tableMetadata.toCreateTableSql();
        logger.info("execute create table sql \n{}", sql);
        executeCreateTableSql(sql);
    }

    public void initDataSQL(ReadInitDataSQL read){
        if(this.init){
            List<String> sqlList = read.read();
            for (String sql : sqlList) {
                if(StrUtil.isBlank(sql) || sql.startsWith("#")){
                    continue;
                }
                String s = StrUtil.format(sql, "PUBLIC");
                logger.info("execute init sql {}", s);
                executeUpdate(s);
            }
        }
    }

}
